﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace SQLH2ConfigTool
{
    public class ConfigurationFile
    {

        XmlDocument xmlConfigFile;

        public ConfigurationFile(string File)
        {
            XmlReaderSettings readerSettings = new XmlReaderSettings();
            readerSettings.IgnoreWhitespace = true;
            readerSettings.IgnoreComments = true;
            readerSettings.CheckCharacters = true;
            readerSettings.CloseInput = true;
            readerSettings.IgnoreProcessingInstructions = false;
            readerSettings.ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None;
            readerSettings.ValidationType = ValidationType.None;

            XmlReader reader = XmlReader.Create(File, readerSettings);
            xmlConfigFile = new XmlDocument();
            xmlConfigFile.Load(reader);
            reader.Close();

            this.FileName = File;
            XmlNodeList Version = xmlConfigFile.GetElementsByTagName("VERSION");

            //get the version
            XmlNode versionNode = (XmlNode)Version[0];
            this.Version = versionNode.Attributes["Value"].Value.ToString();
            
            //get the settings
            XmlNodeList Settings = xmlConfigFile.GetElementsByTagName("SETTINGS");
            XmlNode settingsNode = (XmlNode)Settings[0];

            XmlElement SettingsElement = (XmlElement)settingsNode;

            this.VerboseLogging = Convert.ToBoolean(SettingsElement.GetElementsByTagName("VerboseLogging")[0].Attributes["Value"].Value);
            this.CollectionIntervalSeconds = Convert.ToInt32(SettingsElement.GetElementsByTagName("CollectionIntervalSeconds")[0].Attributes["Value"].Value);
            this.RetryIntervalSeconds = Convert.ToInt32(SettingsElement.GetElementsByTagName("RetryIntervalSeconds")[0].Attributes["Value"].Value);
            this.MaxFileSizeMB = Convert.ToInt32(SettingsElement.GetElementsByTagName("MaxFileSizeMB")[0].Attributes["Value"].Value);

            //Load Servers
            XmlNodeList ServerList = xmlConfigFile.GetElementsByTagName("TARGET_LIST");
            foreach (XmlNode node in ServerList[0])
            {
                Server ReadServer = new Server();
                ReadServer.ServerName = node.Attributes["Name"].Value;
                this.Servers.Add(ReadServer);

                foreach (XmlNode counterNode in node.ChildNodes)
                {
                    Counter ReadCounter = new Counter();
                    ReadCounter.CounterName = counterNode.Attributes["Counter"].Value;
                    ReadCounter.Instance = (counterNode.Attributes["Instance"] != null ? counterNode.Attributes["Instance"].Value : "");
                    ReadCounter.Object = counterNode.Attributes["Object"].Value;

                    ReadServer.Counters.Add(ReadCounter);
                }                
            }
        }
        /* Settings Properties
        * <VerboseLogging Value="true" />
		* <CollectionIntervalSeconds Value="120" />
		* <RetryIntervalSeconds Value="120" />
		* <MaxFileSizeMB Value="1" />
        */

        public void Save()
        {
            //Save a copy first
            string CopyFileName = this.FileName.Replace(".xml", "");
            CopyFileName += DateTime.Now.ToBinary().ToString();
            CopyFileName += ".xml";
            xmlConfigFile.Save(CopyFileName);

            //update and save the file
            SetSettings();
            SetServers();
            SetCounters();

            //save the file
            xmlConfigFile.Save(this.FileName);
        }

        public void SetSettings()
        {
            XmlNode xn;
            XmlNodeList tList;

            xn = xmlConfigFile.SelectSingleNode("/ROOT/SETTINGS");
            tList = xn.ChildNodes;

            foreach (XmlNode tnode in tList)
            {
                switch (tnode.Name)
                {
                    case "VerboseLogging":
                        tnode.SelectSingleNode("attribute::Value").Value = this.VerboseLogging ? "true" : "false";
                        break;
                    case "CollectionIntervalSeconds":
                        tnode.SelectSingleNode("attribute::Value").Value = this.CollectionIntervalSeconds.ToString();
                        break;
                    case "RetryIntervalSeconds":
                        tnode.SelectSingleNode("attribute::Value").Value = this.RetryIntervalSeconds.ToString();
                        break;
                    case "MaxFileSizeMB":
                        tnode.SelectSingleNode("attribute::Value").Value = this.MaxFileSizeMB.ToString();
                        break;
                }
            }
        }

        public void SetServers()
        {
		    XmlNode target;
		    XmlAttribute attr;
		    XmlNode tl = xmlConfigFile.SelectSingleNode ("/ROOT/TARGET_LIST");
		    tl.RemoveAll ();

		    foreach (Server s in this.Servers)
		    {
			    target = xmlConfigFile.CreateNode (XmlNodeType.Element, "TARGET", "");
			    attr = xmlConfigFile.CreateAttribute ("Name");
			    attr.Value = s.ServerName.ToUpper ();
			    target.Attributes.Append (attr);
			    tl.AppendChild (target);
		    }
        }

        public void SetCounters()
        {
            foreach (Server s in this.Servers)
            {
                //xmlConfigFile.SelectSingleNode("/ROOT/TARGET_LIST/TARGET[@Name='S262204RGEW161']")
                XmlNode tl = xmlConfigFile.SelectSingleNode("/ROOT/TARGET_LIST/TARGET[@Name='" + s.ServerName + "']");
                foreach (Counter c in s.Counters)
                {
                    XmlNode PerfCounter = xmlConfigFile.CreateNode(XmlNodeType.Element, "PERFCOUNTER", "");
                    
                    XmlAttribute attrObject = xmlConfigFile.CreateAttribute("Object");
                    attrObject.Value = c.Object.ToUpper();
                    PerfCounter.Attributes.Append(attrObject);

                    XmlAttribute attrCounter = xmlConfigFile.CreateAttribute("Counter");
                    attrCounter.Value = c.CounterName.ToUpper();
                    PerfCounter.Attributes.Append(attrCounter);

                    if (c.Instance != null)
                    {
                        XmlAttribute attrInstance = xmlConfigFile.CreateAttribute("Instance");
                        attrInstance.Value = c.Instance.ToUpper();
                        PerfCounter.Attributes.Append(attrInstance);
                    }

                    tl.AppendChild(PerfCounter);
                }
            }
        }
        
        private string _FileName;
        public string FileName
        {
            get { return _FileName; }
            set { _FileName = value; }
        }

        private string _Version;
        public string Version
        {
            get { return _Version; }
            set { _Version = value; }
        }

        private bool _VerboseLogging;
        public bool VerboseLogging
        {
            get { return _VerboseLogging; }
            set { _VerboseLogging = value; }
        }

        private int _CollectionIntervalSeconds;
        public int CollectionIntervalSeconds
        {
            get { return _CollectionIntervalSeconds; }
            set { _CollectionIntervalSeconds = value; }
        }

        private int _RetryIntervalSeconds;
        public int RetryIntervalSeconds
        {
            get { return _RetryIntervalSeconds; }
            set { _RetryIntervalSeconds = value; }
        }

        private int _MaxFileSizeMB;
        public int MaxFileSizeMB
        {
            get { return _MaxFileSizeMB; }
            set { _MaxFileSizeMB = value; }
        }

        private ServerCollection _Servers = new ServerCollection();
        public ServerCollection Servers
        {
            get { return _Servers; }
            set { _Servers = value; }
        }
    }
}
